﻿using System;

namespace LogikBug.Async.Tasks
{
	public class AgentSettings
	{
		#region Fields

		public static readonly bool DefaultUseThreadPool = true;
		public static readonly int DefaultMaxActiveAgents = 25;
		public static readonly double DefaultTimerInterval = 1.0d;
		public static readonly TimeSpan DefaultExecutionTimeout = TimeSpan.FromMinutes(120.0d);

		#endregion

		#region Constructors

		public AgentSettings() : this(DefaultUseThreadPool, DefaultMaxActiveAgents, DefaultExecutionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(bool useThreadPool) : this(useThreadPool, DefaultMaxActiveAgents, DefaultExecutionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(int maxActiveAgents) : this(DefaultUseThreadPool, maxActiveAgents, DefaultExecutionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(double timerIntervalInMinutes) : this(DefaultUseThreadPool, DefaultMaxActiveAgents, DefaultExecutionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(TimeSpan executionTimeout) : this(DefaultUseThreadPool, DefaultMaxActiveAgents, executionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(bool useThreadPool, int maxActiveAgents) : this(useThreadPool, maxActiveAgents, DefaultExecutionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(bool useThreadPool, double timerIntervalInMinutes) : this(useThreadPool, DefaultMaxActiveAgents, DefaultExecutionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(int maxActiveAgents, double timerIntervalInMinutes) : this(DefaultUseThreadPool, maxActiveAgents, DefaultExecutionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(bool useThreadPool, TimeSpan executionTimeout) : this(useThreadPool, DefaultMaxActiveAgents, executionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(int maxActiveAgents, TimeSpan executionTimeout) : this(DefaultUseThreadPool, maxActiveAgents, executionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(TimeSpan executionTimeout, double timerIntervalInMinutes) : this(DefaultUseThreadPool, DefaultMaxActiveAgents, executionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(bool useThreadPool, int maxActiveAgents, double timerIntervalInMinutes) : this(useThreadPool, maxActiveAgents, DefaultExecutionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(bool useThreadPool, int maxActiveAgents, TimeSpan executionTimeout) : this(useThreadPool, maxActiveAgents, executionTimeout, DefaultTimerInterval)
		{
		}

		public AgentSettings(int maxActiveAgents, TimeSpan executionTimeout, double timerIntervalInMinutes) : this(DefaultUseThreadPool, maxActiveAgents, executionTimeout, timerIntervalInMinutes)
		{
		}

		public AgentSettings(bool useThreadPool, int maxActiveAgents, TimeSpan executionTimeout, double timerIntervalInMinutes)
		{
			UseThreadPool = useThreadPool;
			MaxActiveAgents = maxActiveAgents > DefaultMaxActiveAgents ? DefaultMaxActiveAgents : maxActiveAgents;
			ExecutionTimeout = executionTimeout;
			TimerInterval = timerIntervalInMinutes;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets whether to use the <see cref="System.Threading.ThreadPool"/> to manage threads.
		/// </summary>
		public bool UseThreadPool { get; set; }

		/// <summary>
		/// Gets or sets the maximum number of active executing <see cref="Agents"/>.
		/// </summary>
		public int MaxActiveAgents { get; set; }

		/// <summary>
		/// Gets or sets the <see cref="TimeSpan"/> that
		/// <see cref="Agent"/>s have before timing out.
		/// </summary>
		public TimeSpan ExecutionTimeout { get; set; }

		/// <summary>
		/// Gets or sets the interval in minutes in which the <see cref="TimedAgentController"/> will refresh.
		/// </summary>
		public double TimerInterval { get; set; }

		#endregion
	}
}
